package com.mars.boss.common.quartz;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * Scheduler工具类
 * @类名 SchedulerUtils
 * @日期 2016年12月29日 上午9:05:36
 * @作者 yhaoquan
 * @版权 (c) All Rights Reserved, 2016.
 */
@Component
public class SchedulerUtils {
	
	private static Logger logger = LoggerFactory.getLogger(SchedulerUtils.class) ;
	
	@Autowired
	private Scheduler scheduler ;
	
	
	/**
     * 获取触发器key
     */
    public static TriggerKey getTriggerKey(String jobId, String group) {
    	if(null != group) {
    		return TriggerKey.triggerKey(jobId, group) ;
    	} else {
    		return TriggerKey.triggerKey(jobId);
    	}
    }
    
    /**
     * 获取jobKey
     */
    public static JobKey getJobKey(String jobId, String group) {
    	if(null != group) {
    		return JobKey.jobKey(jobId, group);
    	} else {
    		return JobKey.jobKey(jobId);
    	}
    }

    /**
     * 获取表达式触发器
     */
    public static CronTrigger getCronTrigger(Scheduler scheduler, String jobId, String group) throws SchedulerException {
        try {
            return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId, group));
        } catch (SchedulerException e) {
        	logger.error("获取表达式触发器：" + e);
			throw e ;
        }
    }
    
    /**
     * 通过Spring方式来运行任务
     * @param schedulerJob
     * 			task.beanName 要执行的Spring Bean实例
     * 			task.methodName 要执行的方法
     * 
     */
	public void createScheduleJob(Class<? extends Job> clazz, SchedulerJob schedulerJob) throws SchedulerException {
			try {
				//1: 构建Job信息，运行的类需要实现Job接口
				JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(getJobKey(schedulerJob.getJobId(), schedulerJob.getJobGroup())).withDescription(schedulerJob.getRemarks()).build();
				
				//2: 表达式调度构建器
				CronScheduleBuilder cronSchedule = CronScheduleBuilder.cronSchedule(schedulerJob.getCronExpression()) ;
				
				//3: 按新的cronExpression表达式构建一个新的trigger
				CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(schedulerJob.getJobId(), schedulerJob.getJobGroup())).withSchedule(cronSchedule).build() ;
				
				//4: 创建任务调度
				this.scheduler.scheduleJob(jobDetail, trigger) ;
				
				//设置任务状态
				if(null != schedulerJob.getStatus() && schedulerJob.getStatus() == SchedulerConst.ScheduleStatus.PAUSE.getValue()) {
					pauseJob(schedulerJob);
				}
				
				logger.info("任务创建成功【任务状态：{}   任务ID： {}   任务类：{}   任务触发表达式：{}   任务描述：{}】", 
						SchedulerConst.ScheduleStatus.getEnum(schedulerJob.getStatus()).getDesc(),
						jobDetail.getKey(),
						jobDetail.getJobClass(),
						schedulerJob.getCronExpression(),
						jobDetail.getDescription());
			} catch (SchedulerException e) {
				logger.error("创建任务失败：" + e);
				throw e ;
			}
			
	}
	
	/**
	 * 修改任务调度的触发时间
	 * @param schedulerJob
	 */
	public void rescheduleJob(SchedulerJob schedulerJob) throws SchedulerException {
		try {
            TriggerKey triggerKey = getTriggerKey(schedulerJob.getJobId(), schedulerJob.getJobGroup());

            //表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(schedulerJob.getCronExpression());

            CronTrigger trigger = getCronTrigger(scheduler, schedulerJob.getJobId(), schedulerJob.getJobGroup());
            
            //按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
            
            scheduler.rescheduleJob(triggerKey, trigger);
            
            //设置任务状态
            if(null != schedulerJob.getStatus() && schedulerJob.getStatus() == SchedulerConst.ScheduleStatus.PAUSE.getValue()) {
				pauseJob(schedulerJob);
			}
            
        } catch (SchedulerException e) {
        	logger.error("修改任务调度的触发时间失败：" + e);
			throw e ;
        }
	}
	
	/**
	 * 暂停任务调度
	 * @param schedulerJob
	 */
	public void pauseJob(SchedulerJob schedulerJob) throws SchedulerException {
		try {
			scheduler.pauseJob(getJobKey(schedulerJob.getJobId(), schedulerJob.getJobGroup()));
		} catch (SchedulerException e) {
			logger.error("暂停任务调度失败：" + e);
			throw e ;
		}
	}
	public void pauseJob(String jobId, String jobGroup) throws SchedulerException {
		try {
            scheduler.pauseJob(getJobKey(jobId, jobGroup));
        } catch (SchedulerException e) {
        	logger.error("暂停任务调度失败：" + e);
			throw e ;
        }
	}
	
	/**
	 * 恢复任务调度
	 * @param schedulerJob
	 */
	public void resumeJob(SchedulerJob schedulerJob) throws SchedulerException {
		try {
			scheduler.resumeJob(getJobKey(schedulerJob.getJobId(), schedulerJob.getJobGroup()));
		} catch (SchedulerException e) {
			logger.error("恢复任务调度失败：" + e);
			throw e ;
		}
	}
	public void resumeJob(String jobId, String jobGroup) throws SchedulerException {
		try {
            scheduler.resumeJob(getJobKey(jobId, jobGroup));
        } catch (SchedulerException e) {
        	logger.error("恢复任务调度失败：" + e);
			throw e ;
        }
	}
	
	/**
	 * 删除任务
	 * @param schedulerJob
	 */
	public void deleteJob(SchedulerJob schedulerJob) throws SchedulerException {
		try {
			scheduler.deleteJob(getJobKey(schedulerJob.getJobId(), schedulerJob.getJobGroup()));
		} catch (SchedulerException e) {
			logger.error("删除任务失败：" + e);
			throw e ;
		}
	}
	public void deleteJob(String jobId, String jobGroup) throws SchedulerException {
		try {
            scheduler.deleteJob(getJobKey(jobId, jobGroup));
        } catch (SchedulerException e) {
        	logger.error("删除任务失败：" + e);
			throw e ;
        }
	}
	
	/**
     * 立即执行任务
     */
	public void runNow(SchedulerJob schedulerJob) throws SchedulerException {
		try {
			scheduler.triggerJob(getJobKey(schedulerJob.getJobId(), schedulerJob.getJobGroup()));
		} catch (SchedulerException e) {
			logger.error("立即执行任务：" + e);
			throw e ;
		}
	}
	public void runNow(String jobId, String jobGroup) throws SchedulerException {
		try {
			scheduler.triggerJob(getJobKey(jobId, jobGroup));
		} catch (SchedulerException e) {
			logger.error("立即执行任务：" + e);
			throw e ;
		}
	}
	
}
